#include "../include/elevator.h"

//楼层按键
//灭
char *key_off[10] = {"2-1-1.bmp", "2-2-1.bmp", "2-3-1.bmp", "2-4-1.bmp", "2-5-1.bmp",
					 "2-6-1.bmp", "2-7-1.bmp", "2-8-1.bmp", "2-9-1.bmp", "2-10-1.bmp"};
//亮
char *key_on[10] = {"2-1-2.bmp", "2-2-2.bmp", "2-3-2.bmp", "2-4-2.bmp", "2-5-2.bmp",
					"2-6-2.bmp", "2-7-2.bmp", "2-8-2.bmp", "2-9-2.bmp", "2-10-2.bmp"};

//显示楼层数字
char *floor_num[10] = {"4-1.bmp", "4-2.bmp", "4-3.bmp", "4-4.bmp", "4-5.bmp", 
					   "4-6.bmp", "4-7.bmp", "4-8.bmp", "4-9.bmp", "4-10.bmp"};

//显示楼层场景
char *floor_bmp[10] = {"5-1.bmp", "5-2.bmp", "5-3.bmp", "5-4.bmp", "5-5.bmp", 
					   "5-6.bmp", "5-7.bmp", "5-8.bmp", "5-9.bmp", "5-10.bmp"};

//x_code用于保存对应楼层计算后的对应结果
//x_code 为1表示第一列按钮（1/3/5/7/9层）
//x_code 为0表示第二列按钮（2/4/6/8/10层）
int x_code;

//y_code用于保存对应楼层计算后的对应结果（坐标）				   
int y_code;
 
//触摸屏x，y坐标
int glo_x;
int glo_y;

//用来标识楼层是否被按下
int floor_selection[10] = {0};

//当前楼层
int cur_floor = 1; 
//目标楼层
int tar_floor = 0;

//当前楼层上面有几个楼层被按下
int cur_floor_up_num = 0; 
//当前楼层下面有几个楼层被按下
int cur_floor_down_num = 0; 

//互斥锁
pthread_mutex_t m;

//通过楼层和布局分析每一个楼层对应图片的起始写入点
void calcu_floor_pos(int n)
{
	int x, y;
	x = n % 2;  //计算出楼层的奇偶  奇数x：640  偶数x：720
	y = ((n + 1) / 2 - 1) * 80; //计算出按钮对应的y坐标

	//赋值给全局变量
	x_code = x;
	y_code = y;
}

//打印当前在哪一层，上下方各有多少被按下的层
void analyze_floors()
{
	int nowftemp;
	nowftemp = cur_floor;
	int *p_floor = floor_selection;
	int up_num = 0, down_num = 0;

	//当前楼层上面有几个楼层被按下
	for(int i = nowftemp; i < 11; i ++)
	{
		if(p_floor[i-1] == 1)
		{
			up_num ++;
		}
	}

	//当前楼层下面有几个楼层被按下
	for(int i = nowftemp; i > 0; i --)
	{
		if (p_floor[i-1] == 1)
		{
			down_num ++;
		}
	}

	cur_floor_up_num = up_num;
	cur_floor_down_num = down_num;
	printf("分析：现在在第%d层\n", cur_floor);
	printf("分析：上面还有:%d层被按下, 下面还有:%d层被按下\n", cur_floor_up_num, cur_floor_down_num);
}

void* elev_ctl(void *arg)
{
	pthread_detach(pthread_self());

	int x;//用于计算按下的楼层位置（非坐标）
	int y;//用于计算按下的楼层位置（坐标）

	int status = 0;

	printf("进入按键判断:\n");

	while(1)
	{	
		get_click(&glo_x, &glo_y);
		if(glo_x >= 640 && glo_x <= 800 && glo_y >= 0 && glo_y <= 400)
		{
            struct bmp_info bi;
            bi.pathname = "5-close.bmp";
            bi.offset_x = 200;
            bi.offset_y = 240;

			pthread_mutex_lock(&m);

            pthread_t tid;
            int ret = pthread_create(&tid, NULL, show_bmp_side_to_mid, (void *)&bi);
            if(ret < 0)
            {
                perror("show_bmp_side_to_mid pthread create failed");
                exit(EXIT_FAILURE);
            }
			pthread_mutex_unlock(&m);

			printf("获取坐标值: \n");	

			//按下第几层status就设置为几
			if(glo_x >= 640 && glo_x < 720 && glo_y >= 0 && glo_y < 80)
				status = 1;
			if(glo_x >= 720 && glo_x < 800 && glo_y >= 0 && glo_y < 80)
				status = 2;
			if(glo_x >= 640 && glo_x < 720 && glo_y >= 80 && glo_y < 160)
				status = 3;
			if(glo_x >= 720 && glo_x < 800 && glo_y >= 80 && glo_y < 160)
				status = 4;
			if(glo_x >= 640 && glo_x < 720 && glo_y >= 160 && glo_y < 240)
				status = 5;
			if(glo_x >= 720 && glo_x < 800 && glo_y >= 160 && glo_y < 240)
				status = 6;
			if(glo_x >= 640 && glo_x < 720 && glo_y >= 240 && glo_y < 320)
				status = 7;
			if(glo_x >= 720 && glo_x < 800 && glo_y >= 240 && glo_y < 320)
				status = 8;
			if(glo_x >= 640 && glo_x < 720 && glo_y >= 320 && glo_y < 400)
				status = 9;
			if(glo_x >= 720 && glo_x < 800 && glo_y >= 320 && glo_y < 400)
				status = 10;

			printf("当前按下的是：%d\n", status);
			
			calcu_floor_pos(status);
			if(floor_selection[status-1] == 0)
			{
				if(cur_floor == status)
				{
					if(x_code == 1)
					{
						//对应楼层亮
						show_bmp(key_on[status-1], 640, y_code);
						sleep(1);
						//对应楼层灭
						show_bmp(key_off[status-1], 640, y_code);
					}
					if(x_code == 0)
					{
						//对应楼层亮
						show_bmp(key_on[status-1], 720, y_code);
						sleep(1);
						//对应楼层灭
						show_bmp(key_off[status-1], 720, y_code);
					}
				}
				if(cur_floor != status)
				{
					floor_selection[status-1] = 1;
					analyze_floors();
					if(x_code == 1)
					{
						//对应楼层亮
						show_bmp(key_on[status-1], 640, y_code);
					}
					if(x_code == 0)
					{
						//对应楼层亮
						show_bmp(key_on[status-1], 720, y_code);
					}
				}
			}
			else
			{
				//取消楼层
				floor_selection[status-1] = 0;
				if(x_code == 1)
				{
					show_bmp(key_off[status-1], 640, y_code);//对应楼层灭
				}
				if(x_code == 0)
				{
					show_bmp(key_off[status-1], 720, y_code);//对应楼层灭
				}
				analyze_floors();
			}	
			status = 0;
		}
	}
}

void* warning(void *arg)
{
    pthread_detach(pthread_self());

    pthread_t tid1, tid2, tid3;
    int ret = -1;
    int status = 0;
    int glo_x = 0, glo_y = 0;
    while(1)
    {
        glo_x = glo_y = 0;
        get_click(&glo_x, &glo_y);
        if(glo_x >= 720 && glo_x < 800 && glo_y >= 400 && glo_y < 480 && status == 0)
        {
            printf("发送紧急求救广播\n");

			ret = pthread_create(&tid1, NULL, warning_on, NULL);
			if(ret < 0)
			{
			    perror("warning on pthread create failed");
			    exit(EXIT_FAILURE);
			}

            ret = pthread_create(&tid2, NULL, udp_send, NULL);
            if(ret < 0)
            {
                perror("udp send pthread create failed");
                exit(EXIT_FAILURE);
            }

			ret = pthread_create(&tid3, NULL, show_warning, NULL);
            if(ret < 0)
            {
                perror("udp send pthread create failed");
                exit(EXIT_FAILURE);
            }

            status = 1;
        }
        else if(glo_x > 720 && glo_x < 800 && glo_y > 400 && glo_y < 480 && status == 1)
        {   
			//取消线程
			pthread_cancel(tid1);
            pthread_cancel(tid2);
			pthread_cancel(tid3);
			clean(0x000000, 300, 190, 275, 50);
            printf("取消紧急求救广播\n");
			warning_off();

            status = 0;
        }
    }
}

void elev_init()
{
	//初始化互斥锁
	pthread_mutex_init(&m, NULL);

	//创建五条线程
	int ret = -1;
    pthread_t tid1, tid2, tid3, tid4, tid5;
    //电梯提示播放线程
	ret = pthread_create(&tid1, NULL, tips_display, NULL);
	if(ret < 0)
	{
		printf("tips_display pthread create failed\n");
		return;
	}

	//电梯控制线程
	ret = pthread_create(&tid2, NULL, elev_ctl, NULL);
	if(ret < 0)
	{
		printf("elev_ctl pthread create failed\n");
		return;
	}

	//电梯报警线程
	ret = pthread_create(&tid3, NULL, warning, NULL);
	if(ret < 0)
	{
		printf("warning pthread create failed\n");
		return;
	}

	//tcp控制广告投放线程
    ret = pthread_create(&tid4, NULL, tcp_client_ctl, NULL);
	if(ret < 0)
	{
		printf("tcp_client_ctl pthread create failed\n");
		return;
	}

	//显示时间线程
    ret = pthread_create(&tid5, NULL, show_time, NULL);
	if(ret < 0)
	{
		printf("show_time pthread create failed\n");
		return;
	}

	printf("线程创建完毕，电梯运行\n");
	
	//电梯运行
	int x;//用于放置按下的楼层位置（非坐标）
	int y;//用于放置按下的楼层位置（坐标）

	//sleep(1);
	while(1)
	{
		//电梯向上运行
		for( ; cur_floor_up_num != 0; cur_floor ++)
		{
            show_bmp_side_to_mid1("5-close.bmp", 200, 240); 

			printf("电梯运行中：现在在：第%d层\n", cur_floor);
			printf("电梯运行中：上面还有%d层被按下\n", cur_floor_up_num);
			
			//在屏幕中间显示向上的箭头和当前楼层
			show_bmp("4-up.bmp", 220, 35);
			//sleep(1);
			show_bmp(floor_num[cur_floor - 1], 370, 20);
			
			if(floor_selection[cur_floor - 1] == 1)
			{
				//延时一下, 表示开门                
				//sleep(1);
				//更新数组中的标识位
				floor_selection[cur_floor - 1] = 0;
				//刷新屏幕上的按键情况
				calcu_floor_pos(cur_floor);
				x = x_code;
				y = y_code;
				printf("x = %d  y = %d\n", x, y);
				if(x == 1)
				{
					//到了对应楼层灭
					show_bmp(key_off[cur_floor - 1], 640, y);
					pthread_mutex_lock(&m);
                    show_bmp_mid_to_side(floor_bmp[cur_floor - 1], 200, 240);
					pthread_mutex_unlock(&m);
				}
				if(x == 0)
				{
					//到了对应楼层灭
					show_bmp(key_off[cur_floor - 1], 720, y);
					pthread_mutex_lock(&m);
                    show_bmp_mid_to_side(floor_bmp[cur_floor - 1], 200, 240);
					pthread_mutex_unlock(&m);
					//sleep(1);
				}
				cur_floor_up_num --;
				analyze_floors();
			}
			//延时一下, 表示正在上楼
			sleep(1);
			if (cur_floor_up_num == 0)
			{
				//去掉屏幕中间向上的箭头
				//1. 只刷新屏幕中间的区域, 然后显示当前楼层
				printf("现在在：第%d层\n", cur_floor);
				show_bmp("4-clean.bmp", 200, 0);
				show_bmp(floor_num[cur_floor - 1], 370, 20);
				break;
			}
		}
		
		//电梯向下运行
		for( ; cur_floor_down_num != 0; cur_floor --)
		{
            show_bmp_side_to_mid1("5-close.bmp", 200, 240); 

			printf("电梯运行中：现在在：第%d层\n", cur_floor);
			printf("电梯运行中：下面还有%d层被按下\n", cur_floor_down_num);

			//在屏幕中间显示向下的箭头和当前楼层
			show_bmp("4-down.bmp", 220, 35);
			//sleep(1);
			show_bmp(floor_num[cur_floor - 1], 370, 20);
			if(floor_selection[cur_floor - 1] == 1)
			{
				//播放相应的提示语言
				//延时一下, 表示开门
				//sleep(1);
				//更新数组中的标识位
				floor_selection[cur_floor - 1] = 0;
				//刷新屏幕上的按键情况
				calcu_floor_pos(cur_floor);
				x = x_code;
				y = y_code;
				printf("x = %d, y  = %d\n", x, y);
				if(x == 1)
				{          
					//到了对应楼层灭
					show_bmp(key_off[cur_floor - 1], 640, y);
					pthread_mutex_lock(&m);
                    show_bmp_mid_to_side(floor_bmp[cur_floor - 1], 200, 240);
					pthread_mutex_unlock(&m);
				}
				if(x == 0)
				{
					//到了对应楼层灭
					show_bmp(key_off[cur_floor - 1], 720, y);
					pthread_mutex_lock(&m);
                    show_bmp_mid_to_side(floor_bmp[cur_floor - 1], 200, 240);
					pthread_mutex_unlock(&m);
				}
				cur_floor_down_num --;
				analyze_floors();
			}
			//延时一下, 表示正在下楼
			sleep(1);
			
			if (cur_floor_down_num == 0)
			{
				//去掉屏幕中间向上的箭头
				//1. 只刷新屏幕中间的区域, 然后显示当前楼层
				printf("现在在：第%d层\n", cur_floor);
				show_bmp("4-clean.bmp", 200, 0);
				show_bmp(floor_num[cur_floor - 1], 370, 20);
				break;
			}
		}
	}
}
